﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using WCFServiceWebRole1.Julbock;

namespace WCFServiceWebRole1
{
    // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
    public class Service1 : IService1
    {
        romatimemodelContainer db = new romatimemodelContainer();

        public string GetData(int value)
        {

            User user = new User();
            user.name = "Robin";
            user.password = "asdf";
            user.role = 0;



            db.User.Add(user);
            db.SaveChanges();
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }

        public List<UserUI> getUsers()
        {
            List<UserUI> users = new List<UserUI>();
            foreach (User u in db.User.ToList())
            {
                UserUI userUI = new UserUI();
                userUI.id = u.id;
                userUI.name = u.name;

                users.Add(userUI);
            }

            return users;
        }

        /*public void addUser()
        {
            User u = new User();
            u.name = "Kalle";
            u.username = "StigHelmer";
            u.role = 0;
            u.password = "test";
            db.User.Add(u);
            db.SaveChanges();

        }*/

        public UserUI getUser(string userName)
        {
            try
            {


                User user = db.User.Single(u => u.username.Equals(userName));

                UserUI userUI = new UserUI();
                List<TimeReportUI> timereports = new List<TimeReportUI>();

                foreach (TimeReport report in user.TimeReport)
                {
                    TimeReportUI tempReport = new TimeReportUI();
                    ProjectUI tempProject = new ProjectUI();

                    tempProject.name = report.Project.name;
                    tempProject.role = report.Project.UserRole.Single(role => role.User.Equals(user)).id;

                    tempReport.end = report.stop;
                    tempReport.start = report.start;
                    tempReport.project = tempProject;

                    timereports.Add(tempReport);

                }

                userUI.timeReports = timereports;
                return userUI;
            }
            catch (Exception)
            {

                return null;
            }
        }

        public UserUI getUser(int userId)
        {

            try
            {
                User user = db.User.Single(u => u.id.Equals(userId));

                UserUI userUI = new UserUI();
                List<TimeReportUI> timereports = new List<TimeReportUI>();

                foreach (TimeReport report in user.TimeReport)
                {
                    TimeReportUI tempReport = new TimeReportUI();
                    ProjectUI tempProject = new ProjectUI();

                    tempProject.name = report.Project.name;
                    tempProject.role = report.Project.UserRole.Single(role => role.User.Equals(user)).id;

                    tempReport.end = report.stop;
                    tempReport.start = report.start;
                    tempReport.project = tempProject;

                    timereports.Add(tempReport);

                }

                userUI.timeReports = timereports;
                return userUI;
            }
            catch (Exception e)
            {
                return null;
            }
        }

        public List<TimeReportUI> getTimeReportsForUserBetweenDates(int userId, DateTime start, DateTime stop)
        {

            try
            {



                List<TimeReport> reports = db.TimeReport.Where(report => report.User.id.Equals(userId) &&
                    (((report.start < stop) && (report.start >= start)) || ((report.stop > start)))).ToList();


                List<TimeReportUI> timereports = new List<TimeReportUI>();

                foreach (TimeReport report in reports)
                {
                    TimeReportUI tempReport = new TimeReportUI();
                    ProjectUI tempProject = new ProjectUI();

                    tempProject.name = report.Project.name;
                    tempProject.role = report.Project.UserRole.Single(role => role.User.id.Equals(userId)).id;

                    tempReport.end = report.stop;
                    tempReport.start = report.start;
                    tempReport.project = tempProject;

                    timereports.Add(tempReport);

                }

                return timereports;
            }
            catch (Exception)
            {

                return null;
            }
        }


        public List<TimeReportUI> getTimeReportsForProjectBetweenDates(int projectId, DateTime start, DateTime stop)
        {
            try
            {



                List<TimeReport> reports = db.TimeReport.Where(report => report.Project.id.Equals(projectId) &&
                    (((report.start < stop) && (report.start >= start)) || ((report.stop > start)))).ToList();


                List<TimeReportUI> timereports = new List<TimeReportUI>();

                foreach (TimeReport report in reports)
                {
                    TimeReportUI tempReport = new TimeReportUI();
                    ProjectUI tempProject = new ProjectUI();

                    tempProject.name = report.Project.name;
                    tempProject.role = report.Project.UserRole.Single(role => role.User.id.Equals(projectId)).id;

                    tempReport.end = report.stop;
                    tempReport.start = report.start;
                    tempReport.project = tempProject;

                    timereports.Add(tempReport);

                }

                return timereports;
            }
            catch (Exception)
            {

                return null;
            }
        }


        public List<TimeReportUI> getTimeReportsForUserBetweenDates(string userName, DateTime start, DateTime stop)
        {
            try
            {


                List<TimeReport> reports = db.TimeReport.Where(report => report.User.username.Equals(userName) &&
                    (((report.start < stop) && (report.start >= start)) || ((report.stop > start)))).ToList();


                List<TimeReportUI> timereports = new List<TimeReportUI>();

                foreach (TimeReport report in reports)
                {
                    TimeReportUI tempReport = new TimeReportUI();
                    ProjectUI tempProject = new ProjectUI();

                    tempProject.name = report.Project.name;
                    tempProject.role = report.Project.UserRole.Single(role => role.User.username.Equals(userName)).id;

                    tempReport.end = report.stop;
                    tempReport.start = report.start;
                    tempReport.project = tempProject;

                    timereports.Add(tempReport);

                }

                return timereports;

            }
            catch (Exception)
            {

                throw;
            }
        }




        public TimeSpanUI getTimeSpentOnProjectByUserBetweenDates(int userId, int projectId, DateTime start, DateTime end)
        {
            try
            {



                TimeSpanUI span = new TimeSpanUI();

                List<TimeReport> reports = db.TimeReport.Where(report => report.User.id.Equals(userId) && report.Project.id.Equals(projectId) &&
                    (((report.start < end) && (report.start >= start)) || ((report.stop > start)))).ToList();


                List<TimeReportUI> timereports = new List<TimeReportUI>();
                TimeSpan total = new TimeSpan();

                foreach (TimeReport report in reports)
                {
                    if (report.stop <= end && report.start >= start)
                    {
                        total += report.stop.Subtract(report.start);
                    }
                    else if (report.stop > end && report.start >= start)
                    {
                        total += end.Subtract(report.start);
                    }
                    else if (report.stop > end && report.start < start)
                    {
                        total += end.Subtract(start);
                    }
                    else if (report.stop <= end && report.start < start)
                    {
                        total += report.stop.Subtract(start);
                    }

                }
                span.Hours = total.Hours;
                span.Minutes = total.Minutes;

                return span;
            }
            catch (Exception)
            {

                return null;
            }
        }

        public TimeSpanUI getTimeSpentOnProjectBetweenDates(int projectId, DateTime start, DateTime end)
        {
            try
            {
                TimeSpanUI span = new TimeSpanUI();

                List<TimeReport> reports = db.TimeReport.Where(report => report.Project.id.Equals(projectId) &&
                    (((report.start < end) && (report.start >= start)) || ((report.stop > start)))).ToList();


                List<TimeReportUI> timereports = new List<TimeReportUI>();
                TimeSpan total = new TimeSpan();

                foreach (TimeReport report in reports)
                {
                    if (report.stop <= end && report.start >= start)
                    {
                        total += report.stop.Subtract(report.start);
                    }
                    else if (report.stop > end && report.start >= start)
                    {
                        total += end.Subtract(report.start);
                    }
                    else if (report.stop > end && report.start < start)
                    {
                        total += end.Subtract(start);
                    }
                    else if (report.stop <= end && report.start < start)
                    {
                        total += report.stop.Subtract(start);
                    }

                }
                span.Hours = total.Hours;
                span.Minutes = total.Minutes;

                return span;
            }
            catch (Exception)
            {

                return null;
            }
        }

        public List<UserUI> getUsersInvolvedInProjectWithRole(int projectId, int role)
        {
            try
            {
                List<UserRole> roleList = db.UserRole.Where(roles => roles.Project.id.Equals(projectId) && roles.role.Equals(role)).ToList();
                List<UserUI> users = new List<UserUI>();

                foreach (UserRole tempRole in roleList)
                {

                    UserUI user = new UserUI();
                    user.id = tempRole.User.id;
                    user.name = tempRole.User.name;

                    users.Add(user);
                }

                return users;
            }
            catch (Exception)
            {

                return null;
            }
        }

        public bool addTimeReport(int projectId, int userId, DateTime start, DateTime stop, string description)
        {
            try
            {
                TimeReport report = new TimeReport();
                report.Project = db.Project.Where(project => project.id.Equals(projectId)).Single();
                report.start = start;
                report.stop = stop;
                report.User = db.User.Where(user => user.id.Equals(userId)).Single();
                report.description = description;

                report.User.TimeReport.Add(report);
                report.Project.TimeReport.Add(report);

                db.TimeReport.Add(report);
                db.SaveChanges();
                return true;
            }
            catch (Exception)
            {

                return false;
            }
        }

        public bool addUser(string name, string password, int role, string username)
        {
            try
            {
                User user = new User();
                user.name = name;
                user.password = password;
                user.role = role;
                user.TimeReport = new List<TimeReport>();
                user.username = username;
                user.UserRole = new List<UserRole>();

                db.User.Add(user);
                db.SaveChanges();
                return true;
            }
            catch (Exception)
            {

                return false;
            }
        }

        public List<ProjectUI> getProjectsWithUserInRole(int role, int userId)
        {
            try
            {
                List<UserRole> rolesList = db.UserRole.Where(roles => roles.User.id.Equals(userId) && roles.role.Equals(role)).ToList();
                List<ProjectUI> projects = new List<ProjectUI>();

                foreach (UserRole tempRole in rolesList)
                {
                    ProjectUI tempProject = new ProjectUI();
                    tempProject.name = tempRole.Project.name;

                    projects.Add(tempProject);
                }


                return projects;
            }
            catch (Exception)
            {

                return null;
            }
        }

        public bool addUserRoleInProject(int userId, int projectId, int role)
        {
            try
            {
                UserRole userRole = new UserRole();
                userRole.Project = db.Project.Where(project => project.id.Equals(projectId)).Single();
                userRole.role = role;
                userRole.User = db.User.Where(user => user.id.Equals(userId)).Single();

                db.UserRole.Add(userRole);
                db.SaveChanges();
                return true;
            }
            catch (Exception)
            {

                return false;
            }
        }

        public bool addProject(string name, string description)
        {
            try
            {
                Project project = new Project();
                project.name = name;
                project.TimeReport = new List<TimeReport>();
                project.UserRole = new List<UserRole>();
                project.description = description;
                return true;
            }
            catch (Exception)
            {

                return false;
            }
        }
    }
}
